#include "Game.h"
#include <thread>
#include <Windows.h>
#include <iostream>
#include <conio.h>
using namespace std;
Game::Game(int players)
{
	mutex_pos = new mutex;
	mutex_posUpdate = new deque<pos>;
	p = (Player**) malloc(sizeof(Player*)*players);
	playerPipelines = (threadingInfo**) malloc(sizeof(threadingInfo*)*players);
	for (int i = 0; i<players; i++){
		playerPipelines[i] = new threadingInfo();
		playerPipelines[i]->mutex_kbd = new mutex;
		playerPipelines[i]->mutex_pos = this->mutex_pos;
		playerPipelines[i]->mutex_posUpdate = mutex_posUpdate;
		playerPipelines[i]->mutex_queue = new deque<char>;
		p[i] = new Player(playerPipelines[i], 40, 40, i);
	}
	thread t1(*p[0]), t2(*p[1]);
	thread t3(*this);
	
	t1.join();
	t2.join();
	t3.join();
}

void Game::operator() (){
	while(1){
		while (_kbhit()){
			internalQueue.push_back(_getch());
		}
		while(!internalQueue.empty()){
			char p = internalQueue.front();
			internalQueue.pop_front();
			int playerID = getPlayer(p);
			if (playerID != -1){
				playerPipelines[playerID]->mutex_kbd->lock();
				playerPipelines[playerID]->mutex_queue->push_back(p);
				playerPipelines[playerID]->mutex_kbd->unlock();
			}
		}
		mutex_pos->lock();
		while(!mutex_posUpdate->empty()){
			
			pos p = mutex_posUpdate->front();
			mutex_posUpdate->pop_front();
			HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE) ; 
			COORD position = { p.fromX, p.fromY } ; 
			SetConsoleCursorPosition( hStdout, position ) ; 
			cout << ' ';
			position.X = p.x;
			position.Y = p.y;
			SetConsoleCursorPosition( hStdout, position ) ; 
			cout << char('0' + p.ID);
		}
		mutex_pos->unlock();
	}
}

int Game::getPlayer(char c){
	c = toupper(c);
	int player = -1;
	for (int i = 0; i<2; i++){
		for (int j = 0; j < 4; j++){
			if (controlSets[i][j] == c){
				return i;
			}
		}
	}
	return -1;
}



Game::~Game(void)
{
}

void main(){
	Game g = Game();
}

char Game::controlSets[2][4] = {{'W', 'A', 'S', 'D'}, {'I', 'J', 'K', 'L'}};